__author__ = 'jian.yao'

from misc.errorcode import ERROR_CODE, ERROR_MESSAGE
from usermanage.account.backend import create_user, check_username
from sso.Token.decorators import SSO_getToken
from usermanage.account.decorators import get_user_profile
from usermanage.account.backend import LittleOrangeOnlineServiceAuthBackend

CHANNEL_DOMAINDIC = {
    'littleOrange' : 'localhost'
}

SSO_DOMAIN = 'localhost'
DEFAULT_CHANNEL = 'littleOrange'

def sso_user_login(_uname, _password):
    if not _uname or not _password:
        return ERROR_CODE.PARAMETERS_ERROR, ERROR_MESSAGE.PARAMETERS_ERROR, None, None
    if not check_username(_uname):
        return ERROR_CODE.INVALID_USERNAME, ERROR_MESSAGE.INVALID_USERNAME, None, None
    userObj = LittleOrangeOnlineServiceAuthBackend()
    username = userObj.authenticate(_uname, _password)
    if username is None:
        return ERROR_CODE.INCORRECT_USERNAMEORPASSWORD, ERROR_MESSAGE.INCORRECT_USERNAMEORPASSWORD, None, None

    User = get_user_profile(username)
    Token, errcode, errorMes = SSO_getToken(User.id)
    if Token is None:
        return errcode, errorMes, None, None

    return ERROR_CODE.SUCCESS, ERROR_MESSAGE.SUCCESS, User, Token

def getDefaultChannel(channel = None):
    return DEFAULT_CHANNEL

def getDoUrl(channel, action = None):
    doUrl = {'littleOrange' : {'reg' : 'http://127.0.0.1:8000/ws/sso/web/user-do-reg',
                                'login' : 'http://127.0.0.1:8000/ws/sso/web/user-do-login',
                                'commodity_add' : 'http://127.0.0.1:8000/warehouse/commodity/do-add'}
            }
    if action is None or action == '':
        action = 'reg'
    return doUrl[channel][action]

def getCookieExp(channel):
    cookieExpDic = {
        'littleOrange' : {'maxAge' : 100, 'exp' : 1000},
        'sso' : {'maxAge' : 100, 'exp' : 1000},
    }
    if channel is None or channel not in cookieExpDic:
        return cookieExpDic['sso']
    else:
        return cookieExpDic[channel]

def getChannelDomain(channel = None):
    if channel is None or channel not in CHANNEL_DOMAINDIC:
        return SSO_DOMAIN
    return CHANNEL_DOMAINDIC[channel]

def getSSODomain():
    return SSO_DOMAIN

def getSSOExp(channel = None):
    return {'maxAge' : 100, 'exp' : 9999}

def getChannelDomain(channel = None):
    if channel is None or channel not in CHANNEL_DOMAINDIC:
        return SSO_DOMAIN
    return CHANNEL_DOMAINDIC[channel]

def sso_user_reg(username, password, channel = 'littleOrange'):
    if username is None or password is None or channel is None:
        return ERROR_CODE.PARAMETERS_ERROR, ERROR_MESSAGE.PARAMETERS_ERROR, None, None
    checkUserNameRes, code, mes = check_username(username)
    if checkUserNameRes is False:
        return code, mes, None, None

    user = create_user(channel, username, password)
    if user is None:
        return ERROR_CODE.UNKNOWN_ERROR, ERROR_MESSAGE.UNKNOWN_ERROR, None, None

    userProfile = get_user_profile(user)
    uid = userProfile.id
    token, errcode, errorMes = SSO_getToken(uid)
    # if token is None:
    #     return ERROR_CODE.errcode, ERROR_MESSAGE.errcode, None, None
    return errcode, errorMes, userProfile, token

def setCookie(valueDic, channel = None, response = None, oper = 'set', setSso = True):
    if not isinstance(valueDic, dict) or len(valueDic) < 1:
        return False
    if response is None:
        return False
    if channel is None or channel == '':
        channel = getDefaultChannel()
    domain = getChannelDomain()
    exp = getCookieExp(channel)
    ssoDomain = getSSODomain()
    ssoExp = getSSOExp()
    try:
        for k in valueDic.iterkeys():
            if oper == 'set':
                response.set_cookie(k, valueDic[k], exp['maxAge'], exp['exp'], '/', domain)
                if setSso is True:
                    response.set_cookie(k, valueDic[k], ssoExp['maxAge'], ssoExp['exp'], '/', ssoDomain)
            else:
                response.delete_cookie(k, '/', domain)
    except Exception:
        return False

    return True
